home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / nhclb120.zoo / sys5_io.c < prev    next >
C/C++ Source or Header  |  1992-05-28  |  9KB  |  499 lines

  1. /* OS- and machine-dependent stuff for SYS5 */
  2.  
  3. /*
  4.     FILE: UNIX.io.c
  5.     
  6.     Routines:
  7.         ioinit()
  8.         iostop()
  9.         asy_init()
  10.         asy_stop()
  11.         asy_speed()
  12.         asy_output()
  13.         asy_recv()
  14.         dir()
  15.     Written or converted by Mikel Matthews, N9DVG
  16.     SYS5 added by Jere Sandidge, K4FUM
  17.     Directory pipe added by Ed DeHart, WA3YOA
  18.     Numerous changes by Charles Hedrick and John Limpert, N3DMC
  19.     Hell, *I* even hacked on it... :-)  Bdale, N3EUA
  20.     
  21.     If you want to use the select code, define SELECT in the makefile or
  22.     in this file.
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <termio.h>
  28. #include <signal.h>
  29. #include <sys/file.h>
  30. #include <sys/dir.h>
  31. #include <time.h>
  32. #include <sys/time.h>
  33. #include <fcntl.h>
  34. #include <memory.h>
  35. #include <string.h>
  36. #include "global.h"
  37. #include "asy.h"
  38. #include "mbuf.h"
  39. #include "internet.h"
  40. #include "iface.h"
  41. #include "unix.h"
  42. #include "cmdparse.h"
  43.  
  44. #ifndef    B19200
  45. #define    B19200    EXTA
  46. #endif
  47.  
  48. #ifndef    B38400
  49. #define    B38400    EXTB
  50. #endif
  51.  
  52. struct asy asy[ASY_MAX];
  53. struct interface *ifaces;
  54. struct termio mysavetty, savecon;
  55. int savettyfl;
  56. int    IORser[ASY_MAX];
  57. extern unsigned long selmask;
  58.  
  59. /* Called at startup time to set up console I/O, memory heap */
  60. ioinit()
  61. {
  62.     struct termio ttybuf;
  63.     extern void ioexit();
  64.  
  65.     (void) signal(SIGHUP, ioexit);
  66.     (void) signal(SIGINT, ioexit);
  67.     (void) signal(SIGQUIT, ioexit);
  68.     (void) signal(SIGTERM, ioexit);
  69.  
  70.     ioctl(0, TCGETA, &ttybuf);
  71.     savecon = ttybuf;
  72.  
  73.     ttybuf.c_iflag &= ~(ICRNL);
  74.     ttybuf.c_lflag &= ~(ICANON|ISIG|ECHO);
  75.     ttybuf.c_cc[VTIME] = '\01';
  76.     ttybuf.c_cc[VMIN] = '\0';
  77.     if ((savettyfl = fcntl(0, F_GETFL, 0)) == -1) {
  78.         perror("Could not read console flags");
  79.         return -1;
  80.     }
  81.  
  82. /* #ifdef  undef */
  83.     fcntl(0, F_SETFL, savettyfl | O_NDELAY);
  84. /* #endif */
  85.  
  86.     ioctl(0, TCSETAW, &ttybuf);
  87.     return 0;
  88. }
  89.  
  90.  
  91. /* Called just before exiting to restore console state */
  92. void
  93. iostop()
  94. {
  95.     setbuf(stdout,NULLCHAR);
  96.  
  97.     while (ifaces != NULLIF) {
  98.         if (ifaces->stop != NULLFP)
  99.             (*ifaces->stop)(ifaces->dev);
  100.         ifaces = ifaces->next;
  101.     }
  102.  
  103.     ioctl(0, TCSETAW, &savecon);
  104.     fcntl(0, F_SETFL, savettyfl);
  105. }
  106.  
  107. void
  108. ioexit()
  109. {
  110.     iostop();
  111.     exit(0);
  112. }
  113.  
  114. void
  115. clearout()
  116. {
  117.     fflush(stdout);
  118.     ioctl(1, TCFLSH, 1);
  119. }
  120.  
  121. void
  122. flowon()
  123. {
  124.     struct termio ttybuf;
  125.     ioctl(0, TCGETA, &ttybuf);
  126.     ttybuf.c_iflag |= IXON;
  127.     ioctl(0, TCSETAW, &ttybuf);
  128. }
  129.  
  130. void
  131. flowoff()
  132. {
  133.     struct termio ttybuf;
  134.     ioctl(0, TCGETA, &ttybuf);
  135.     ttybuf.c_iflag &= ~IXON;
  136.     ioctl(0, TCSETAW, &ttybuf);
  137. }
  138.  
  139. void
  140. flowdefault()
  141. {
  142.     struct termio ttybuf;
  143.     ioctl(0, TCGETA, &ttybuf);
  144.     if (savecon.c_iflag & IXON)
  145.         ttybuf.c_iflag |= IXON;
  146.     else
  147.         ttybuf.c_iflag &= ~IXON;
  148.     ioctl(0, TCSETAW, &ttybuf);
  149. }
  150.  
  151. /* Initialize asynch port "dev" */
  152. /*ARGSUSED*/
  153. int
  154. asy_init(dev, arg1, arg2, bufsize)
  155. int16 dev;
  156. char *arg1, *arg2;
  157. unsigned bufsize;
  158. {
  159.     register struct asy *ap;
  160.     struct termio    sgttyb;
  161.  
  162. #ifdef    SYS5_DEBUG
  163.     printf("asy_init: called\n");
  164. #endif    /* SYS5_DEBUG */
  165.  
  166.     if (dev >= nasy)
  167.         return -1;
  168.  
  169.     ap = &asy[dev];
  170.     ap->tty = malloc((unsigned)(strlen(arg2)+1));
  171.     strcpy(ap->tty, arg2);
  172.     printf("asy_init: tty name = %s\n", ap->tty);
  173.  
  174.     if ((IORser[dev] = open(ap->tty, (O_RDWR|O_NDELAY), 0)) < 0) {
  175.         perror("Could not open device IORser");
  176.         return -1;
  177.     }
  178.     selmask |= (1 << IORser[dev]);
  179.  
  180.  /* 
  181.   * get the stty structure and save it 
  182.   */
  183.  
  184.     if (ioctl(IORser[dev], TCGETA, &mysavetty) < 0)    {
  185.         perror("ioctl failed on device");
  186.         return -1;
  187.     }
  188.  
  189.  /* 
  190.   * copy over the structure 
  191.   */
  192.  
  193.     sgttyb = mysavetty;
  194.     sgttyb.c_iflag = (IGNBRK | IGNPAR);
  195.     sgttyb.c_oflag = 0;
  196.     sgttyb.c_lflag = 0;
  197.     sgttyb.c_cflag = (B9600 | CS8 | CREAD);
  198.     sgttyb.c_cc[VTIME] = 0;
  199.     sgttyb.c_cc[VMIN] = 0;
  200.  
  201.     if (ioctl(IORser[dev], TCSETAF, &sgttyb) < 0) {
  202.         perror("ioctl could not set parameters for IORser");
  203.         return -1;
  204.     }
  205.  
  206.     return 0;
  207. }
  208.  
  209.  
  210. /*ARGSUSED*/
  211. int
  212. asy_stop(iface)
  213. struct interface *iface;
  214. {
  215. }
  216.  
  217.  
  218. /* Set asynch line speed */
  219. int
  220. asy_speed(dev, speed)
  221. int16 dev;
  222. int speed;
  223. {
  224.     struct termio sgttyb;
  225.  
  226.     if (speed == 0 || dev >= nasy)
  227.         return -1;
  228.  
  229. #ifdef    SYS5_DEBUG
  230.     printf("asy_speed: Setting speed for device %d to %d\n",dev, speed);
  231. #endif
  232.  
  233.     asy[dev].speed = speed;
  234.  
  235.     if (ioctl(IORser[dev], TCGETA, &sgttyb) < 0) {
  236.         perror("ioctl could not get parameters");
  237.         return -1;
  238.     }
  239.  
  240.     sgttyb.c_cflag &= ~CBAUD;
  241.  
  242.     switch ((unsigned)speed) {
  243.     case 0:
  244.         sgttyb.c_cflag |= B0;
  245.         break;
  246.     case 50:
  247.         sgttyb.c_cflag |= B50;
  248.         break;
  249.     case 75:
  250.         sgttyb.c_cflag |= B75;
  251.         break;
  252.     case 110:
  253.         sgttyb.c_cflag |= B110;
  254.         break;
  255.     case 134:
  256.         sgttyb.c_cflag |= B134;
  257.         break;
  258.     case 150:
  259.         sgttyb.c_cflag |= B150;
  260.         break;
  261.     case 200:
  262.         sgttyb.c_cflag |= B200;
  263.         break;
  264.     case 300:
  265.         sgttyb.c_cflag |= B300;
  266.         break;
  267.     case 600:
  268.         sgttyb.c_cflag |= B600;
  269.         break;
  270.     case 1200:
  271.         sgttyb.c_cflag |= B1200;
  272.         break;
  273.     case 1800:
  274.         sgttyb.c_cflag |= B1800;
  275.         break;
  276.     case 2400:
  277.         sgttyb.c_cflag |= B2400;
  278.         break;
  279.     case 4800:
  280.         sgttyb.c_cflag |= B4800;
  281.         break;
  282.     case 9600:
  283.         sgttyb.c_cflag |= B9600;
  284.         break;
  285.     case 19200:
  286.         sgttyb.c_cflag |= B19200;
  287.         break;
  288.     case 38400:
  289.         sgttyb.c_cflag |= B38400;
  290.         break;
  291.     default:
  292.         printf("asy_speed: Unknown speed (%d)\n", speed);
  293.         break;
  294.     }
  295.  
  296. #ifdef    SYS5_DEBUG
  297.     printf("speed = %d\n", sgttyb.sg_ispeed);
  298. #endif    /* SYS5_DEBUG */
  299.  
  300.     if (ioctl(IORser[dev], TCSETAW, &sgttyb) < 0) {
  301.         perror("ioctl could not set parameters for IORser");
  302.         return -1;
  303.     }
  304.  
  305.     return 0;
  306. }
  307.  
  308.  
  309. /* Send a buffer to serial transmitter */
  310. asy_output(dev, buf, cnt)
  311. unsigned dev;
  312. char *buf;
  313. unsigned short cnt;
  314. {
  315. #ifdef    SYS5_DEBUG
  316.     printf("asy_output called. dev = %d, cnt = %d\n", dev, cnt);
  317.     printf("buf = %lx\n", (long) buf);
  318.     fflush(stdout);
  319. #endif
  320.     
  321.     if (dev >= nasy)
  322.         return -1;
  323.  
  324.     if (write(IORser[dev], buf, (int)cnt) < cnt) {
  325.         perror("asy_output");
  326.         printf("asy_output: error in writing to device %d\n", dev);
  327.         return -1;
  328.     }
  329.  
  330.     return 0;
  331. }
  332.  
  333. /* Receive characters from asynch line
  334.  * Returns count of characters read
  335.  */
  336. int16
  337. asy_recv(dev,buf,cnt)
  338. int16 dev;
  339. char *buf;
  340. unsigned cnt;
  341. {
  342. #define    IOBUFLEN    256
  343.     extern int    errno;
  344.     unsigned tot;
  345.     int r;
  346.     static struct    {
  347.         char    buf[IOBUFLEN];
  348.         char    *data;
  349.         int    cnt;
  350.     }    IOBUF[ASY_MAX];
  351.  
  352. #ifdef SELECT
  353.     int    mask;
  354.     int    writemask;
  355.     int    ok;
  356.     struct timeval timeout;
  357.  
  358.     if(IOBUF[dev].cnt == 0) {
  359.     timeout.tv_sec = 0;
  360.     timeout.tv_usec = 35;
  361.     mask = (1<<IORser[dev]) | 1;
  362.     writemask = (1<<IORser[dev]);
  363.     ok = 0;
  364.     tot = 0;
  365.     ok = select(20, &mask, 0, 0, 0);
  366.     }
  367. #ifdef undef
  368.     if ( mask & (1<<IORser[dev]))
  369.     {
  370.         tot = read(IORser[dev], buf, cnt);
  371.     }
  372.     return (tot);
  373. #endif
  374. #endif
  375.     if(IORser[dev] < 0) {
  376.         printf("asy_recv: bad file descriptor passed for device %d\n",
  377.             dev);
  378.         return(0);
  379.     }
  380.     tot = 0;
  381.     /* fill the read ahead buffer */
  382. #ifdef notdef
  383.     if(IOBUF[dev].cnt == 0 && (rdchk(IORser[dev]) > 0)) {
  384. #else
  385.     if(IOBUF[dev].cnt == 0) {
  386. #endif
  387.         IOBUF[dev].data = IOBUF[dev].buf;
  388.         r = read(IORser[dev], IOBUF[dev].data, IOBUFLEN);
  389.         /* check the read */
  390.         if (r == -1) {
  391.             IOBUF[dev].cnt = 0;    /* bad read */
  392.             if (errno != 11) {  /* ewouldblock */
  393.                 perror("asy_recv");
  394.                 printf("asy_recv: error in reading from device %d\n", dev);
  395.             }
  396.             return(0);
  397.         } else
  398.             IOBUF[dev].cnt = r;
  399.     } 
  400.     r = 0;    /* return count */
  401.     /* fetch what you need with no system call overhead */
  402.     if(IOBUF[dev].cnt > 0) {
  403.         if(cnt == 1) { /* single byte copy, do it here */
  404.             *buf = *IOBUF[dev].data++;
  405.             IOBUF[dev].cnt--;
  406.             r = 1;
  407.         } else { /* multi-byte copy, left memcpy do the work */
  408.             unsigned n = min(cnt, IOBUF[dev].cnt);
  409.             memcpy(buf, IOBUF[dev].data, n);
  410.             IOBUF[dev].cnt -= n;
  411.             IOBUF[dev].data += n;
  412.             r = n;
  413.         }
  414.     }
  415.     tot = (unsigned int) r;
  416.     return (tot);
  417. }
  418.  
  419. /* Generate a directory listing by opening a pipe to /bin/ls.
  420.  * If full == 1, give a full listing; else return just a list of names.
  421.  */
  422. FILE *
  423. dir(path,full)
  424. char *path;
  425. int full;
  426. {
  427.     FILE *fp;
  428.     char cmd[1024];
  429.  
  430.     if (path == NULLCHAR || path[0] == '\0')
  431.         path = ".";
  432.  
  433. #ifdef    SYS5_DEBUG
  434.     printf("DIR: path = %s\n", path);
  435. #endif    /* SYS5_DEBUG */
  436.  
  437.     if (full)
  438.         sprintf(cmd,"ls -l %s", path);
  439.     else
  440.         sprintf(cmd, "ls %s", path);
  441.  
  442.     if ((fp = popen(cmd,"r")) == NULLFILE) {
  443.         perror("popen");
  444.         return NULLFILE;
  445.     }
  446.  
  447.     return fp;
  448. }
  449.  
  450.  
  451. asy_ioctl(interface, argc, argv)
  452. struct interface *interface;
  453. int    argc;
  454. char    *argv[];
  455. {
  456.     if (argc < 1) {
  457.         printf("%d\r\n", asy[interface->dev].speed);
  458.         return 0;
  459.     }
  460.  
  461.     return asy_speed(interface->dev, atoi(argv[0]));
  462.